Post

Replies

Boosts

Views

Activity

Reply to `PageTabViewStyle` for `TabView` doesn't work with adding new Page
struct TabViewTest: View {     @State private var selection = 0     @State private var contents = ["a","b","c"]     @State private var update = UUID()     var body: some View {         VStack{         TabView(selection:$selection){             ForEach(0..<contents.count,id:\.self){ i in                 Text(contents[i])                     .tag(i)             }         }         .tabViewStyle(PageTabViewStyle(indexDisplayMode: .automatic))         .id(update)             Button("add"){                 contents.append("ddd")                 let old = selection                 update = UUID()                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {                     selection = old                 }             }         }     } }
Jul ’20
Reply to Popping back multiple levels?
Try NavigationViewKit https://github.com/fatbobman/NavigationViewKit import NavigationViewKit NavigationView { List(0..<10) { _ in NavigationLink("abc", destination: DetailView()) } } .navigationViewManager(for: "nv1", afterBackDo: {print("back to root") }) in any view in NavigationView @Environment(\.navigationManager) var nvmanager Button("back to root view") { nvmanager.wrappedValue.popToRoot(tag:"nv1"){ print("other back") } } You can also call it through NotificationCenter without calling it in the view let backToRootItem = NavigationViewManager.BackToRootItem(tag: "nv1", animated: false, action: {}) NotificationCenter.default.post(name: .NavigationViewManagerBackToRoot, object: backToRootItem)
Sep ’21
Reply to Question about sharing data via Cloudkit and Core Data - Creating CKShare
Sorry, I made a mistake in my description in the previous feedback. After continuous testing, I found that the problem is not with how to create ckshare, but with the sharing permissions. When the owner sets the share permissions for the data to a specific icloud user, the program works perfectly. The participant can show the share record in their app as soon as they accept the invitation. When the owner sets the data sharing permission to anyone, the participant does not show the shared data after accepting the invitation. Only when the owner makes changes to the data can it be displayed, and only the modified data can be displayed. For example, a demo is provided in my GitHub Shared Data for Note , Note has a relationship to multiple Memo When the owner shares a Note (sharing permission is set to anyone), the participant does not show the Note in the first time, and only after the owner adds a new Memo to the Note, the participant's app will show it, and only show that after the sharing is added. When sharing for a specific icloud user, the participant can show the Note at the first time, and if the Note already has Memo data at the time of sharing, the participant will also show all the Memo data added before sharing. May I ask if this is the logical mechanism of sharing preset? Or is it a bug?
Sep ’21
Reply to NSPersistentCloudKitContainer Bug
I'm struggling with these issues now too. Currently Core Data with CloudKit backs up all NSManagedObjects corresponding to CKRecord as well as CKShare for efficiency reasons, which should be done locally. As a result, even if the developers modify the CKShare data by code, they still can't get the local ckshare catch updated. This makes it difficult for developers to design their own UICloudShareingController. Currently the local ckshare is not updated after stopping sharing using the UICloudSharingController, resulting in the ckshare effectively being disabled. This results in the UICloudSharingController not being able to use it for initialisation. I tried deleting the customzone on the server via code, and after deletion, the shared customzone would continue to be restored after the next app cold start due to the local catch mechanism. ideally, the data should be moved from the customzone back to the private customzone after the owner stops sharing, com.apple.coredata .cloudkit.zone, and update the local catch to remove the CKShare corresponding to the shared NSManageObjct There is no notification mechanism available on the participant side when an owner pair disables a participant share. The current situation is that the share record on the participant's device is not working well at this point, and when the user clicks on it, it crashes the application. I would like to be able to get an alert on the participant side that the share has been stopped, so that the code can easily handle it. After the participant stops sharing of their own accord, the local ckshare is refreshed but does not disappear and the shared data disappears the next time the app is cold-launched, but if the app is not cold-launched and the user clicks on the shared data, it will cause the program to crash. My current solution is to delete the local NSManagedObject for that share in the callback method
Sep ’21
Reply to NSPersistentCloudKitContainer Bug
I have submitted a Feedback to Apple. Updates to ckshare in the cache can currently be resolved by persistUpdatedShare. The issue of deleting custom Zones after stopping a share is solved by purgeObjectsAndRecordsInZone. There is still a lot of work to be done on your own though. Also, the UICloudSharingController still does not automatically use the above methods. I have written a small demo https://github.com/fatbobman/ShareData_Demo_For_CoreDataWithCloudKit
Sep ’21
Reply to Questions about CSSearchQuery and Spotlight
Thank you for your reply. I have submitted feedback regarding the Chinese characters. FB9639611 In my own code, I have used a similar scheme to yours, fuzzy querying Chinese Latin spelling results from CoreData data. extension String{     func transformToLatin(hasBlank: Bool = false) -> String {         let stringRef = NSMutableString(string: self) as CFMutableString         CFStringTransform(stringRef,nil, kCFStringTransformToLatin, false)         CFStringTransform(stringRef, nil, kCFStringTransformStripCombiningMarks, false)         let pinyin = stringRef as String         return hasBlank ? pinyin : pinyin.replacingOccurrences(of: " ", with: "")     } } I will try again as you suggested.
Sep ’21
Reply to Hot to merge Predicate in SwiftData
Thank you for your reply. However, in some cases, I need to prepare some predicates in advance and combine them according to some conditions during the running of the app. This is also the main use of NSCompoundPredicate in this situation. However, in the new Predicate, no similar mechanism is provided. I feel that PredicateExpression may provide a corresponding method, but I haven't found it yet.
Aug ’23
Reply to SwiftData with two Stores
This should be a bug. By using SwiftDataKit to inspect the information of NSPersistentStoreCoordinator, I found that only the store corresponding to the first configuration is loaded. // ModelContainer(for: Schema([Item.self,Tag.self]), configurations: [configuration2,configuration1]) let coordinator = context.coordinator print(coordinator?.persistentStores.count) // 1 Interestingly, SwiftData creates a separate sqlite file for each configuration. I suppose this has already been reported to Feedback, and now we can only wait for Apple to resolve this issue.
Dec ’23
Reply to Has anyone successfully used NSStagedMigrationManager?
I attempted to create a model by directly accessing the Managed Object Model (MOM), and the code ran successfully. I also completed the migration process. The implementation is somewhat obscure, and I believe Apple's main purpose in providing this migration method for Core Data is to offer a foundational implementation for phased migrations in SwiftData. guard let momdURL = Bundle.main.url(forResource: "Model", withExtension: "momd") else { fatalError() } let model1URL = momdURL.appending(component: "Model.mom") let model2URL = momdURL.appending(component: "Model 2.mom") guard let model1 = NSManagedObjectModel(contentsOf: model1URL) else { fatalError() } guard let model2 = NSManagedObjectModel(contentsOf: model2URL) else { fatalError() } let v1ModelChecksum = model1.versionChecksum let v1ModelReference = NSManagedObjectModelReference(model: model1, versionChecksum: v1ModelChecksum) let v2ModelChecksum = model2.versionChecksum let v2ModelReference = NSManagedObjectModelReference(model: model2, versionChecksum: v2ModelChecksum) let customStage = NSCustomMigrationStage( migratingFrom: v1ModelReference, to: v2ModelReference ) let migrationManager = NSStagedMigrationManager([customStage]) let description = container.persistentStoreDescriptions.first description?.setOption(migrationManager, forKey: NSPersistentStoreStagedMigrationManagerOptionKey) and I have update my topic about staged migration of Core Data. https://fatbobman.com/en/posts/what-s-new-in-core-data-in-wwdc23
Feb ’24
Reply to onChange stops working after triggering navigationDestination(isPresented:destination:) within NavigationLink
I adjusted the code to the following form to better reflect the problem of onChange in a multi-layer nested navigation hierarchy. class ViewModel: ObservableObject { @Published var count = 0 } struct Root: View { @StateObject private var viewModel = ViewModel() var body: some View { NavigationStack { SubView(level: 1) .navigationDestination(for: Int.self) { value in SubView(level: value) } } .environmentObject(viewModel) } } struct SubView: View { let level: Int @EnvironmentObject var viewModel: ViewModel var body: some View { VStack { let _ = print("level \(level) Update: \(viewModel.count)") Text("Level: \(level)") Text("Count: \(viewModel.count)") Button("Count++") { viewModel.count += 1 } NavigationLink(value: level + 1) { Text("Goto New Level") } } .task(id: viewModel.count) { print("Level \(level) onTaskID: \(viewModel.count)") } .onChange(of: viewModel.count){ _ in print("Level \(level) onChange: \(viewModel.count)") } .onReceive(viewModel.$count){ _ in print("Level \(level) onReceive: \(viewModel.count)") } } } Clicking "Goto New Level" will add a level, and clicking "Count++" will increase the count value by one When the navigation exceeds 2 levels, only the bottom and top onChange closures will respond No matter how many levels of navigation there are, only the top task(id:) will respond No matter how many levels of navigation there are, onReceive at each level will respond Not sure if this is intentional or a bug, I will submit a feedback to Apple later
Nov ’24
Reply to Why first View on my NavigationStack appears again when I switch branch?
The problem is similar to the one described at https://forums.developer.apple.com/forums/thread/719521, where onAppear is triggered unexpectedly. The following patterns can currently be summarized: The navigation container must be within a conditional branch. The navigation container needs to perform certain operations (such as entering a new navigation page or creating multiple navigation container instances). Unexpected calls occur when switching to a branch that does not include the navigation container. This issue occurs only in iOS. I have submitted feedback as well. Details can be found here: https://fatbobman.com/en/posts/traps-and-countermeasures-for-abnormal-onappear-calls-in-swiftui/
2w